#include <iostream>
#include <assert.h>
using namespace std;


namespace my_vector
{
	template <class T>
	class vector
	{
	public:
		typedef T* iterator;
		typedef const T* const_iterator;
		vector():_start(nullptr),_end(nullptr),_size(nullptr)
		{
			;
		}

		vector(const int n)
		{
			_start = new T[n];
			_end = _start + n - 1;
			_size = _start;
		}

		vector(int n, const T& value = T())
		{
			reserve(n);
			for (int i = 0; i < n; i++)
			{
				push_back(value);
			}
		}

		vector(const vector<T>& v)
		{
			reserve(v.capacity());
			for (const auto e : v)
			{
				push_back(e);
			}
		}

		vector<T>& operator=(const vector<T>& v)
		{
			reserve(v.capacity());
			for (const auto e : v)
			{
				push_back(e);
			}
		}

		T& operator[](size_t n)
		{
			assert(capacity() > n && n >= 0);
			return _start + n;
		}

		const T& operator[](size_t n)const
		{
			assert(capacity() > n && n >= 0);
			return _start + n;
		}

		~vector()
		{
			delete[] _start;
			_start = _end = _size;
		}

		size_t size()
		{
			return _size - _start;
		}

		size_t capacity()
		{
			return _end - _start;
		}

		void swap(vector<T> v)
		{
			std::swap(v._start, _start);
			std::swap(v._end, _end);
			std::swap(v._size, _size);
		}

		void reserve(size_t n)
		{
			assert(n >= 0);
			if (n > capacity())
			{
				T* ret = new T[n];
				size_t pos = size();
				memcpy(ret, _start, sizeof(T) * n);
				if (_start != nullptr)
				{
					delete[] _start;
				}
				_start = ret;
				_size = _start + pos;
				_end = _start + n - 1;
			}
		}

		void resize(size_t n, const T& value = T())
		{
			assert(n >= 0);
			if (n > capacity())
			{
				T* ret = new T[n];
				size_t pos = size();
				memcpy(ret, _start, sizeof(T) * n);
				if (_start != nullptr)
				{
					delete[] _start;
				}
				_start = ret;
				_size = _start + pos;
				_end = _start + n - 1;
				strncpy(_size, value, sizeof(T) * (n - size()));
			}
			else
			{
				_size = _start + n;
			}
		}

		void insert(T* pos, const T& v)
		{
			assert(pos >= _start && pos <= _size);
			if (_end == _size)
			{
				size_t p = pos - _start;
				int n = size() == 0 ? 4 : size() * 2;
				reserve(n);
				pos = p + _start;
			}
			memmove(pos + 1, pos, sizeof(T) * (size() - (pos - _start - 1)));
			*_size = v;
			_size++;
		}

		void erase(T* pos)
		{
			assert(size() != 0 && pos >= _start && _size >= pos);
			memmove(pos, pos + 1, sizeof(T) * (pos - _start - 1));
			_size--;
		}

		void push_back(const T& v)
		{
			if (_end == _size)
			{
				int n = size() == 0 ? 4 : size() * 2;
				reserve(n);
			}
			*_size = v;
			_size++;
		}

		void push_back(const T& v)const
		{
			insert(_size, v);
		}

		void pop_back()
		{
			_size--;
		}

		void pop_back()const
		{
			erase(_size);
		}
		
		iterator begin()
		{
			return _start;
		}

		iterator end()
		{
			return _size - 1;
		}

		const_iterator cbegin()const
		{
			return _start;
		}

		const_iterator cend()const
		{
			return _size - 1;
		}

	private:
		T* _start;
		T* _end;
		T* _size;
	};
}

int main()
{
	my_vector::vector<int> v(10);
	v.push_back(5);
	v.push_back(6);
	v.push_back(7);
	cout << v.size() << endl;;
	v.pop_back();
	return 0;
}